package kr.ac.konkuk.db.quadtree.server;

import java.io.Closeable;

import kr.ac.konkuk.db.quadtree.QuadTree;
import kr.ac.konkuk.db.quadtree.RowKey;
import kr.ac.konkuk.db.quadtree.callback.GeometryProvider;
import kr.ac.konkuk.db.quadtree.impl.QuadTreeImpl;
import kr.ac.konkuk.db.quadtree.server.service.QuadTreeService;
import kr.ac.konkuk.db.quadtree.server.service.QuadTreeServiceHandler;

import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;

public class QuadTreeServer implements Closeable {
	private static final Logger logger = LoggerFactory
			.getLogger(QuadTreeServer.class);
	private QuadTree<Geometry> geomQt;
	private TServer server = null;
	private TNonblockingServerSocket socket = null;

	public QuadTreeServer(QuadTree<Geometry> geomQt) {
		this.geomQt = geomQt;
	}

	public void bind(int port) throws TTransportException {
		QuadTreeService.Iface qtService = new QuadTreeServiceHandler(geomQt);

		socket = new TNonblockingServerSocket(port);
		QuadTreeService.Processor<QuadTreeService.Iface> processor = new QuadTreeService.Processor<QuadTreeService.Iface>(
				qtService);
		THsHaServer.Args args = new THsHaServer.Args(socket);
		args.processor(processor);
		args.inputTransportFactory(new TFramedTransport.Factory());
		args.inputProtocolFactory(new TBinaryProtocol.Factory());
		server = new THsHaServer(args);

		logger.info("started port : {}", port);
		server.serve();
	}

	public void close() {
		if (server != null) {
			server.stop();
		}
		if (socket != null) {
			socket.close();
		}
	}

	public static void main(String[] args) throws TTransportException {
		QuadTree<Geometry> qt = new QuadTreeImpl(new Envelope(179124, 216175,
				436239, 466556), new GeometryProvider() {

			@Override
			public Geometry getGeometry(RowKey rowKey) {
				return null;
			}

		});

		QuadTreeServer qtServer = null;
		try {
			qtServer = new QuadTreeServer(qt);
			qtServer.bind(9090);
		} finally {
			if (qtServer != null) {
				qtServer.close();
			}
		}
	}
}
